#include "Bank_i.h"
#include <iostream>
#include <fstream>
#include "ace/streams.h"
#include "tao/ORB_Core.h"
#include "Naming_Service/Naming_Service.h"

int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) {
    try {
        // Initialize the ORB.
        CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

		// Get reference to POA(Portable Object Adaptor)
		CORBA::Object_var obj_poa = orb->resolve_initial_references("RootPOA");
		PortableServer::POA_var rootPOA = PortableServer::POA::_narrow (obj_poa.in());		
		PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager();
		poa_manager-> activate();
		
		// establish policies
		CORBA::PolicyList policies(2);
		policies.length(2);
		policies[0] = rootPOA-> create_id_assignment_policy(PortableServer::USER_ID);
		policies[1] = rootPOA-> create_thread_policy(PortableServer::ORB_CTRL_MODEL);

		PortableServer::POA_var poaMH = rootPOA-> create_POA("POAMH", poa_manager.in(), policies);
		policies[0]-> destroy();
		policies[1]-> destroy();

		// Create servant
	        PortableServer::ServantBase_var servant = new Bank_i();
		// Assign ID.
		PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId("ATM");

		// Active servant in POA.
		poaMH-> activate_object_with_id(oid.in(), servant.in());

		// By IOR
		ifstream myfile ("ns.ior");
		CORBA::String_var ior;
		myfile >> ior;

		// Get reference by name service
		CORBA::Object_var naming_context_object = orb-> string_to_object(ior);
		CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow(naming_context_object.in ());
	
		// Create and initialize the object.
		CosNaming::Name name(1);
		name.length(1);		
		name[0].id = PortableServer::ObjectId_to_string(oid);
		
		// Register object in name server
		naming_context-> bind(name, poaMH->id_to_reference(oid));

		// Print IOR in screen
		cout << ior.in() << endl;


/*        obj = poa->id_to_reference( oid.in() );
        CORBA::String_var str = orb->object_to_string( obj.in() );
        std::ofstream iorFile( "Bank.ior" );
        iorFile << str.in() << std::endl;
        iorFile.close();
        std::cout << "IOR written to file Messenger.ior" << std::endl;*/

        // Accept requests from clients.
        orb->run();

	// Destroy POA with active wait
	rootPOA-> destroy (1, 1);
        orb->destroy();
        return 0;
    }
    catch(const CORBA::Exception& ex) {
        std::cerr << "CORBA exception: " << ex << std::endl;
    }
    return 1;
}
